• 函数模板的定义:

    1
    template<TYPE_LIST, ARG_LIST>Function_Definition

    其中,Function_Definition为函数定义:TYPE_LIST被称为类型参数表,是由一系列代表类型的标识符组成的,其间用逗号分隔,这些标识符的风格通常是由大写字母组成,ARG_LIST称为变量表,其中含有由逗号分隔开的多个变量声明,相当于一般函数定义中的形式参数。

  • 对于类模板,当在类外定义类中的成员函数时,需在每个成员函数的定义前面加上template说明。

  • 函数模板与类模板的区别

    • 我们在使用函数模板时不一定必须指明T的类型,函数模板的实例化可以由编译程序在处理函数调用时自动完成,例如当调用max(1, 2)时自动生成实例max<int>,而调用max(1.1f, 2.2f)时自动生成实例max<float, float>,当然也可以显式指定T的类型;
    • 而对于类模板来说,其实例化必须被显式的指定,比如Point_T<int, int>Point_T<float, float>
    • 在设计模板的时候应当注意将C++模板中与参数无关的代码分离出来,避免代码膨胀
    • 模板类的实例个数是由类型参数的种类决定的
  • 函数模板的特化:函数模板需要对某种类型进行特别处理,例如:

    1
    2
    3
    4
    5
    6
    7
    bool IsEqual(T t1, T t2) {
    return t1 == t2;
    }
    template<>
    bool IsEqual(char* t1, char* t2) { // 函数模板特化
    return strcmp(t1, t2) == 0;
    }

    这样,当IsEqual函数的参数类型为char*时,就会调用IsEqual特化的版本,而不会再用函数模板实例化。

  • 类模板的特化:当类模板内需要对某些类型进行特别处理时,使用类模板的特化,例如

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    template <class T>
    class compare {
    public:
    bool IsEqual(T t1, T t2) {
    return t1 == t2;
    }
    };
    template<>
    class compare<char*> //特化(char*) {
    public:
    bool IsEqual(char* t1, char* t2) {
    return strcmp(t1, t2) == 0;
    }
    }

    需要注意的是进行类模板的特化时,需要特化所有的成员变量和成员函数

  • 部分模板特例化和全部模板特例化

    全部模板特例化就是模板中的模板参数全被指定为确定的类型,也就是定义了一个全新的类型,全部模板特例化的类中的函数可以与模板类不一样,例如:

    1
    2
    3
    4
    template <class A, class B, class C>
    class X {};
    template<>
    class X<int, float, string> {};

    部分模板特例化是指模板中的模板参数没有被全部确定,需要编译器在编译时进行确定,它通常有两种情况:

    • 对部分模板参数进行特例化

      1
      2
      template <class B, class C>
      class X <int, B, C> {};

      当编译器遇到X<int, float, string>的模板实例化请求时,使用这个特例化的版本,而当编译器遇到X<int, doule, char>时,也是使用这个特例化版本,也就是说,只要X<>实例化时, 第一个模板实参是int,就是用特例化版本。

    • 使用具有某一特征的类型,对模板参数进行特例化:

      1
      2
      3
      4
      template <class T>
      class Y {}; // (d)
      template <class T>
      class Y<T*> {}; // (e)

      当编译器遇到Y<int*>时,使用特例化模板(e),当编译器遇到T<float*>时,也使用特例化模板(e),而其他类型的实例化时,如Y<int>,使用基本模板(d),也就是说,当模板实参符合特例化版本所需的特征时(在上面例子中时某个类型的指针),则使用特例化版本。